/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package control;

import com.opensymphony.xwork2.ActionSupport;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import util.md5Util;
import pojo.User;

import java.util.Date;

import service.IUserService;

import debug.Debugger;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.ParseException;
import java.util.HashMap;
import javax.servlet.http.HttpServletResponse;
import pojo.Image;
import service.IImageService;

/**
 *
 * @author administrator
 */
public class UserAction extends ActionSupport {
    // General property

    private User user;
    private IUserService<User> userService;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public IUserService<User> getUserService() {
        return userService;
    }

    public void setUserService(IUserService<User> userService) {
        Debugger.checkPoint((userService != null), "userService hooked in UserAction");

        this.userService = userService;
    }
    // End of eneral property
    // Login section
    private String uni;
    private String password;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUni() {
        return uni;
    }

    public void setUni(String uni) {
        this.uni = uni;
    }
    //End of login section

//    private String loginInputPage = "login.jsp";
//
//    public String getLoginInputPage() {
//        return loginInputPage;
//    }
//
//    public void setLoginInputPage(String loginInputPage) {
//        this.loginInputPage = loginInputPage;
//    }
//    public String login() throws Exception {
//        Debugger.msg(String.format("UserAction.login() called with variables uni=%s password=%s", uni, password));
//
//        // check user
//        this.user = userService.getUser(uni, password);
//        if (user == null) {
//            // user not exist
//            return "error";
//        } else {
//            // user exists, create a session if not already
//            HttpServletRequest request = ServletActionContext.getRequest();
//            HttpSession session = request.getSession(true);
//            session.setAttribute("user", this.user);
//            session.setAttribute("uni", this.uni);
//            session.setAttribute("tab", "base");
//            return "main";
//        }
//    }
//    public String out() throws Exception {
//        Debugger.msg(String.format("UserAction.out() called with variables ..."));
//
//        HttpServletRequest request = ServletActionContext.getRequest();
//        HttpSession session = request.getSession(false);
//
//        session.removeAttribute("user");
//        return "main";
//    }
//    private String displayProfileBasicInputPage = "/UserSetting.jsp";
//
//    public String getDisplayProfileBasicInputPage() {
//        return displayProfileBasicInputPage;
//    }
//
//    public void setDisplayProfileBasicInputPage(String displayProfileBasicInputPage) {
//        this.displayProfileBasicInputPage = displayProfileBasicInputPage;
//    }
    // Basic Setting Section
    public String displayProfileBasic() throws Exception {
        Debugger.msg(String.format("UserAction.displayProfileBasic() called with variables ... %s", updateSuccess));

        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession(false);
        if (session == null) {
            return "login";
        } else {
            this.user = (User) session.getAttribute("user");
            this.dob = user.getDateOfBirth();
            Debugger.checkPoint((user != null), String.format("user variable fetched from session attribute with unikey: %s, faculty: %s", user.getUnikey(), user.getDescription()));
            session.setAttribute("tab", "base");
            return "setting";
        }
    }
    private Date dob;
    private java.text.SimpleDateFormat fm = new java.text.SimpleDateFormat("dd/MM/yyyy");

    public String getDob() {
        return fm.format(dob);
    }

    public void setDob(String dob) {
        try {
            fm.setLenient(false);
            this.dob = fm.parse(dob);
        } catch (ParseException e) {
            Debugger.handleException(e);
        }
    }
    private boolean updateSuccess = false;

    public boolean isUpdateSuccess() {
        return updateSuccess;
    }

    public void setUpdateSuccess(boolean updateSuccess) {
        this.updateSuccess = updateSuccess;
    }

    public String updateProfileBasic() throws Exception {
        Debugger.msg(String.format("UserAction.updateProfileBasic() called with variables ...%s, %s, %s", user.getUnikey(), user.getDescription(), dob));

        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession(false);
        if (session == null) {
            return "login";
        } else {
            User current_user = (User) session.getAttribute("user");
            current_user.setDateOfBirth(dob);
            current_user.setGender(user.getGender());
            current_user.setDescription(user.getDescription());
            current_user.setEmail(user.getEmail());
            current_user.setFaculty(user.getFaculty());
            try {
                userService.updateUser(current_user);
                updateSuccess = true;
                session.setAttribute("user", current_user);
                session.setAttribute("tab", "base");
                return "setting";
            } catch (RuntimeException e) {
                Debugger.msg(e.getMessage());
                Debugger.handleException(e);
                return "error";
            }
        }
    }
    // End of Basic Setting Section
    // password section
    private String oldpwd = null;
    private String newpwd = null;
    private String check_pwd = null;

    public String getCheck_pwd() {
        return check_pwd;
    }

    public void setCheck_pwd(String check_pwd) {
        this.check_pwd = check_pwd;
    }

    public String getNewpwd() {
        return newpwd;
    }

    public void setNewpwd(String newpwd) {
        this.newpwd = newpwd;
    }

    public String getOldpwd() {
        return oldpwd;
    }

    public void setOldpwd(String oldpwd) {
        this.oldpwd = oldpwd;
    }

    public String changePassword() throws Exception {
        Debugger.msg(String.format("UserAction.changePassword() called with variables oldpwd=%s newpwd=%s check_pwd=%s", oldpwd, newpwd, check_pwd));

        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession(false);
        if (session == null) {
            // no session: error
            return "login";
        }
        this.user = (User) session.getAttribute("user");
        if (user == null) {
            // no User obj stored in the session: error
            return "error";
        }
        // note that when comparing passwords, the pw in the User obj is md5 encrypted
        // while the other vars passed in r plain pw
        if (!user.getPassword().equals(md5Util.calc(oldpwd))) {
            // old password does not match the current password: error
            return "error";
        }
        if (!newpwd.equals(check_pwd)) {
            // new password does not match the reconfirming password: error
            return "error";
        }
        this.user.setPassword(md5Util.calc(newpwd));
        try {
            this.user = userService.updateUser(this.user);
            session.setAttribute("user", this.user);
            session.setAttribute("tab", "safe");
            updateSuccess = true;
            return "setting";
        } catch (RuntimeException e) {
            Debugger.msg(e.getMessage());
            return "login";
        }
    }
    // end of password section
    // Avatar section
    private File avatar;
    private Image image;
    private IImageService<Image> imageService;

    public IImageService<Image> getImageService() {
        return imageService;
    }

    public void setImageService(IImageService<Image> imageService) {
        Debugger.checkPoint((imageService != null), "imageService hooked in UserAction");
        this.imageService = imageService;
    }

    public void setAvatar(File avatar) {

        this.avatar = avatar;
    }

    public String upload_avatar() throws Exception {
        Debugger.msg(String.format("UserAction.upload_avatar() called with variables ..."));
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession(false);
        if (session == null) {
            // no session: error
            return "login";
        }
        byte[] img = null;
        if (avatar != null) {
            FileInputStream fis = new FileInputStream(avatar);
            if (fis != null) {
                int len = fis.available();
                img = new byte[len];
                fis.read(img);
            }
        }
        else
        {
            String t = request.getParameter("pic");
            if(t == null)
            {
                return "upload_avatar_success";
            }
            int len = Integer.valueOf(request.getParameter("len"));
            img = new byte[len];
            img = new sun.misc.BASE64Decoder().decodeBuffer(t);
        }
            this.user = this.userService.findUserByUni((String) session.getAttribute("uni"));
            if (this.user.getImage().getImageID() == 0) {
                this.image = new Image(img);
                this.imageService.createImage(this.image);
                this.user.setImage(this.image);
            } else {
                this.image = user.getImage();
                this.image.setImage(img);
//                this.image = new Image(img);
//                this.image.setImageID(user.getImage().getImageID());
//                this.user.setImage(this.image);
            }
            session.removeAttribute("user");
            this.userService.updateUser(this.user);
            session.setAttribute("user", this.user);
        session.setAttribute("tab", "face");
        updateSuccess = true;
        return "upload_avatar_success";
    }

    public void get_avatar() throws IOException {
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession(false);

        this.user = (User) session.getAttribute("user");
        Debugger.msg(String.format("UserAction.get_avatar() called with variables ..."));
        HttpServletResponse response = ServletActionContext.getResponse();
        response.setContentType("image/jpeg");
        this.user = userService.findUserByUni(this.uni);
        Integer i = this.user.getImage().getImageID();
        this.image = imageService.findImageByID(i);
        response.reset();
        response.getOutputStream().write(image.getImage());
        response.getOutputStream().flush();
    }
    // End of Avatar section

    public String home() {
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession(false);

        session.setAttribute("tab", "base");
        if (session == null) {
            // no session: error
            return "login";
        }
        return "main";
    }

    public String test() throws IOException
    {
        HttpServletRequest request = ServletActionContext.getRequest();
        String t = request.getParameter("pic");
        int len = Integer.valueOf(request.getParameter("len"));
        byte[] bytes = new byte[len];
	bytes = new sun.misc.BASE64Decoder().decodeBuffer(t);
        BufferedOutputStream stream = null;
        File file = null;
        file = new File("D:\\1.jpeg");
        FileOutputStream fstream = new FileOutputStream(file);
        stream = new BufferedOutputStream(fstream);
        stream.write(bytes);
        stream.flush();
        stream.close();
        return "login";
    }
}
